﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;
using Workflows.Components;
using Workflows.Components.Entities.Distances;
using Workflows.Components.Entities.Providers;
using Workflows.Components.Entities.Relations.InferredAssociations;

namespace Workflows.Components.Entities.StreamCollapse
{
    public partial class StreamingCollapseEditor : Form, IComponentEditor 
    {
        #region fields
        private object _ActivityNode;
        private StreamingCollapseComponent _CollapseComponent;
        private Dictionary<string, AttributeMetaData> _AttributeMetaDatas;
        private Dictionary<string, IAttributeDistanceCalcutor> _Comparers;
        private Dictionary<string, ICollapseCalculator> _CollapseCalcs;
        #endregion

        public StreamingCollapseEditor()
        {
            InitializeComponent();
        }

        private void CollapseEditor_Load(object sender, EventArgs e)
        {
            this._Comparers = new Dictionary<string, IAttributeDistanceCalcutor>();
            this._CollapseCalcs = new Dictionary<string, ICollapseCalculator>();
            this._AttributeMetaDatas = new Dictionary<string, AttributeMetaData>();

            Assembly assembly = this.GetType().Assembly;
            Type[] types = assembly.GetTypes();
            foreach (Type type in types)
            {
                if (type.GetInterface(typeof(IAttributeDistanceCalcutor).FullName) != null)
                {
                    IAttributeDistanceCalcutor comparer = (IAttributeDistanceCalcutor)Activator.CreateInstance(type);
                    this._Comparers.Add(type.FullName, comparer);
                }
                if (type.GetInterface(typeof(ICollapseCalculator).FullName) != null)
                {
                    ICollapseCalculator clusterCalculator = (ICollapseCalculator)Activator.CreateInstance(type);
                    this._CollapseCalcs.Add(type.FullName, clusterCalculator);
                }
            }

            this.cbo_Comparers.Items.Clear();
            foreach (string comparerName in this._Comparers.Keys)
            {
                this.cbo_Comparers.Items.Add(comparerName);
            }
            this.cbo_CollapseCalc.Items.Clear();
            foreach (string clusterCalcName in this._CollapseCalcs.Keys)
            {
                this.cbo_CollapseCalc.Items.Add(clusterCalcName);
            }
        }

        #region IComponentEditor Members

        public event UpdateComponentSettings UpdateComponentSettingEvent;

        public object OwnerActivityNode
        {
            get { return _ActivityNode; }
            set { _ActivityNode=value; }
        }

        public Type WorkflowComponentType
        {
            get { return typeof(StreamingCollapseComponent); }
        }

        public void LoadSettings(GlobalVariable[] globalVars, WorkflowComponentBase[] fromComponents,
                                 object activityNode, WorkflowComponentBase wfComponent)
        {
            this._ActivityNode = activityNode;
            this._CollapseComponent = (StreamingCollapseComponent) wfComponent;

            if(!string.IsNullOrEmpty(this._CollapseComponent.PartitionedEntityProviderFilePath))
            {
                this.ck_PartitionProvider.Checked = true;
                this.txt_EntityProviderFilePath.Text = this._CollapseComponent.PartitionedEntityProviderFilePath;
            }
            this.cbo_DbProvider.SelectedIndex = (int)this._CollapseComponent.DbProvider;
            this.txt_ConnStr.Text = this._CollapseComponent.ConnStr;
            this.rt_SQL.Text = this._CollapseComponent.SelectSql;

            // columns
            this._AttributeMetaDatas = new Dictionary<string, AttributeMetaData>();
            this.cbo_IdAttribute.Items.Clear();
            this.cbo_PartitionAttribute.Items.Clear();
            if(!string.IsNullOrEmpty(this.txt_ConnStr.Text) && !string.IsNullOrEmpty(this.rt_SQL.Text))
            {
                TableColumn[] srcCols = DbUtil.GetTableColumns(this._CollapseComponent.DbProvider,
                                                               this.txt_ConnStr.Text, this.rt_SQL.Text);
                if(srcCols !=null && srcCols.Length>0)
                {
                    foreach(TableColumn col in srcCols)
                    {
                        this.cbo_IdAttribute.Items.Add(col.ColumnName);
                        this.cbo_PartitionAttribute.Items.Add(col.ColumnName);
                    }
                }
            }

            // attrs
            this.dv_Attributes.Rows.Clear();
            if (this._CollapseComponent.AttrMetaDatas !=null && this._CollapseComponent.AttrMetaDatas.Count>0)
            {
                foreach (AttributeMetaData attributeMetaData in this._CollapseComponent.AttrMetaDatas)
                {
                    this._AttributeMetaDatas.Add(attributeMetaData.AttributeName, attributeMetaData);
                    
                    DataGridViewRow dr = new DataGridViewRow();
                    DataGridViewTextBoxCell cellAttrName = new DataGridViewTextBoxCell();
                    if (attributeMetaData.AttributeType == AttributeType.CompositeAttribute)
                    {
                        string binding = string.Empty;
                        string[] argNames = new string[attributeMetaData.ArgNameAttrNameBindings.Count];
                        attributeMetaData.ArgNameAttrNameBindings.Keys.CopyTo(argNames, 0);
                        for (int i = 0; i < argNames.Length; i++)
                        {
                            string attrName = attributeMetaData.ArgNameAttrNameBindings[argNames[i]];
                            this.AddAttributeForPerformanceFilter(attrName);
                            binding += argNames[i] + "=" + attrName;
                            if (i < argNames.Length - 1)
                                binding += ",";
                        }
                        cellAttrName.Value = binding;
                    }
                    else
                    {
                        cellAttrName.Value = attributeMetaData.AttributeName;
                        this.AddAttributeForPerformanceFilter(attributeMetaData.AttributeName);
                    }
                    dr.Cells.Add(cellAttrName);

                    DataGridViewComboBoxCell cellAttrType = new DataGridViewComboBoxCell();
                    for (int i = 0; i <= 4; i++)
                    {
                        AttributeType attrType = (AttributeType) i;
                        cellAttrType.Items.Add(attrType.ToString());
                    }
                    cellAttrType.Value = attributeMetaData.AttributeType.ToString();
                    dr.Cells.Add(cellAttrType);
                    DataGridViewTextBoxCell cellPosW = new DataGridViewTextBoxCell();
                    cellPosW.Value = attributeMetaData.PositiveMatchWeight;
                    dr.Cells.Add(cellPosW);
                    DataGridViewTextBoxCell cellNegW = new DataGridViewTextBoxCell();
                    cellNegW.Value = attributeMetaData.NegativeMatchWeight;
                    dr.Cells.Add(cellNegW);
                    DataGridViewComboBoxCell cellComparers = new DataGridViewComboBoxCell();
                    foreach (string comparerTypeName in this._Comparers.Keys)
                    {
                        cellComparers.Items.Add(comparerTypeName);
                    }
                    cellComparers.Value = attributeMetaData.ComparerTypeName;
                    dr.Cells.Add(cellComparers);

                    DataGridViewCheckBoxCell cellExternal = new DataGridViewCheckBoxCell();
                    cellExternal.Value = attributeMetaData.IsExternalAttribute;
                    dr.Cells.Add(cellExternal);

                    DataGridViewComboBoxCell cellDbProvider = new DataGridViewComboBoxCell();
                    for (int i = 0; i <= 1;i++)
                    {
                        cellDbProvider.Items.Add(((DataProviderType) i).ToString());
                    }
                    cellDbProvider.Value = attributeMetaData.ExternalAttributeDbProvider.ToString();
                    dr.Cells.Add(cellDbProvider);

                    DataGridViewTextBoxCell cellConnStr = new DataGridViewTextBoxCell();
                    cellConnStr.Value = attributeMetaData.ExternalAttributeConnStr;
                    dr.Cells.Add(cellConnStr);

                    DataGridViewTextBoxCell cellSql = new DataGridViewTextBoxCell();
                    cellSql.Value = attributeMetaData.ExternalAttributeSelectSql;
                    dr.Cells.Add(cellSql);

                    DataGridViewTextBoxCell cellSettings = new DataGridViewTextBoxCell();
                    string settings = string.Empty;
                    if (attributeMetaData.ComparerSettings != null && attributeMetaData.ComparerSettings.Count > 0)
                    {
                        string[] names = new string[attributeMetaData.ComparerSettings.Count];
                        attributeMetaData.ComparerSettings.Keys.CopyTo(names, 0);
                        for (int i = 0; i < names.Length; i++)
                        {
                            settings += names[i] + ":=" + attributeMetaData.ComparerSettings[names[i]];
                            if (i < names.Length - 1)
                                settings += ",";
                        }
                    }
                    cellSettings.Value = settings;
                    dr.Cells.Add(cellSettings);

                    this.dv_Attributes.Rows.Add(dr);
                }
            }

            if(this.cbo_IdAttribute.Items.Count>0 && !string.IsNullOrEmpty(this._CollapseComponent.IdAttributeName))
            {
                for(int i=0;i<this.cbo_IdAttribute.Items.Count;i++)
                {
                    if(this.cbo_IdAttribute.Items[i].ToString()==this._CollapseComponent.IdAttributeName)
                    {
                        this.cbo_IdAttribute.SelectedIndex = i;
                        break;
                    }
                }
            }

            // threshold
            if(this._CollapseComponent.NativeAttributeThreshold >0)
            {
                this.ck_NativeAttrThreshold.Checked = true;
                this.num_NativeAttrThreshold.Value = (decimal)this._CollapseComponent.NativeAttributeThreshold;
            }
            else
            {
                this.ck_NativeAttrThreshold.Checked = false;
            }
            if(this._CollapseComponent.AssociativeAttributeThreshold>0)
            {
                this.ck_AssociativeAttrThreshold.Checked = true;
                this.num_AssociativeAttrThreshold.Value =
                    (decimal) this._CollapseComponent.AssociativeAttributeThreshold;
            }
            else
            {
                this.ck_AssociativeAttrThreshold.Checked = false;
            }
            if(this._CollapseComponent.CollapseScoreThreshold >0)
            {
                this.ck_CollapseThreshold.Checked = true;
                this.num_CollapseThreshold.Value = (decimal)this._CollapseComponent.CollapseScoreThreshold;
            }
            else
            {
                this.ck_CollapseThreshold.Checked = false;
            }


            // collapse calc 
            if(this.cbo_CollapseCalc.Items.Count>0 && (!string.IsNullOrEmpty(this._CollapseComponent.CollapseCalculatorTypeName)))
            {
                for(int i=0;i<this.cbo_CollapseCalc.Items.Count;i++)
                {
                    if(this.cbo_CollapseCalc.Items[i].ToString()==this._CollapseComponent.CollapseCalculatorTypeName)
                    {
                        this.cbo_CollapseCalc.SelectedIndex = i;
                        break;
                    }
                }
            }

            // partitions  
            this.dv_ClusterAttributes.Rows.Clear();
            if(this._CollapseComponent.PartitionAttributes !=null && 
                this._CollapseComponent.PartitionAttributes.Count>0)
            {
                foreach(EntityPartitionAttribute partAttr in this._CollapseComponent.PartitionAttributes.Values)
                {
                    DataGridViewRow dr = new DataGridViewRow();
                    
                    DataGridViewTextBoxCell cellAttrNames = new DataGridViewTextBoxCell();
                    cellAttrNames.Value = partAttr.PartitionAttributeName;
                    dr.Cells.Add(cellAttrNames);

                    DataGridViewCheckBoxCell cellExt=new DataGridViewCheckBoxCell();
                    cellExt.Value = partAttr.IsExternal;
                    dr.Cells.Add(cellExt);

                    DataGridViewComboBoxCell cellDbProvider = new DataGridViewComboBoxCell();
                    cellDbProvider.Items.Add(DataProviderType.MSSQL.ToString());
                    cellDbProvider.Items.Add(DataProviderType.Oracle.ToString());
                    cellDbProvider.Value = partAttr.DbProvider.ToString();
                    dr.Cells.Add(cellDbProvider);

                    DataGridViewTextBoxCell cellConnStr=new DataGridViewTextBoxCell();
                    cellConnStr.Value = partAttr.ConnStr;
                    dr.Cells.Add(cellConnStr);

                    DataGridViewTextBoxCell cellSql=new DataGridViewTextBoxCell();
                    cellSql.Value = partAttr.SelectSql;
                    dr.Cells.Add(cellSql);

                    DataGridViewTextBoxCell cellEntityIDField=new DataGridViewTextBoxCell();
                    cellEntityIDField.Value = partAttr.EntityIDFieldName;
                    dr.Cells.Add(cellEntityIDField);

                    this.dv_ClusterAttributes.Rows.Add(dr);
                }
            }

            // merges 
            this.clb_AvailableMergeableAttrs.Items.Clear();
            if(this._CollapseComponent.AttrMetaDatas !=null && this._CollapseComponent.AttrMetaDatas.Count>0)
            {
                foreach (AttributeMetaData attributeMetaData in this._CollapseComponent.AttrMetaDatas)
                {
                    this.clb_AvailableMergeableAttrs.Items.Add(attributeMetaData.AttributeName);
                }
            }
            this.dv_MergeableAttrs.Rows.Clear();
            if(this._CollapseComponent.MergeableAttributeNames !=null && this._CollapseComponent.MergeableAttributeNames.Count>0)
            {
                for(int i=0;i<this._CollapseComponent.MergeableAttributeNames.Count;i++)
                {
                    List<string> attrNames = this._CollapseComponent.MergeableAttributeNames[i];
                    DataGridViewRow dr = new DataGridViewRow();
                    DataGridViewTextBoxCell cellAttrNames=new DataGridViewTextBoxCell();
                    cellAttrNames.Value = StringUtil.ToString(attrNames.ToArray());
                    dr.Cells.Add(cellAttrNames);
                    this.dv_MergeableAttrs.Rows.Add(dr);
                }
            }

            // collapse instance  
            this.dv_CollapseInstanceFields.Rows.Clear();
            if (!string.IsNullOrEmpty(this._CollapseComponent.TgtConnStr))
            {
                this.rd_TgtDB.Checked = true;
                this.txt_TgtConnStr.Text = this._CollapseComponent.TgtConnStr;
                string[] tblNames =
                    DbUtil.GetTableNames(DataProviderType.MSSQL, string.Empty, this._CollapseComponent.TgtConnStr);
                this.cbo_CollapseInstanceTable.Items.Clear();
                this.cbo_CollapseMappingTable.Items.Clear();
                if(tblNames !=null && tblNames.Length>0)
                {
                    foreach(string tblName in tblNames)
                    {
                        this.cbo_CollapseInstanceTable.Items.Add(tblName);
                        this.cbo_CollapseMappingTable.Items.Add(tblName);
                    }

                    if(!string.IsNullOrEmpty(this._CollapseComponent.CollapseInstanceTable))
                    {
                        for(int i=0;i<this.cbo_CollapseInstanceTable.Items.Count;i++)
                        {
                            if(this.cbo_CollapseInstanceTable.Items[i].ToString()==this._CollapseComponent.CollapseInstanceTable)
                            {
                                this.cbo_CollapseInstanceTable.SelectedIndex = i;
                                break;
                            }
                        }
                    }

                    if(!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingTable))
                    {
                        for(int i=0;i<this.cbo_CollapseMappingTable.Items.Count;i++)
                        {
                            if(this.cbo_CollapseMappingTable.Items[i].ToString()==this._CollapseComponent.CollapseMappingTable)
                            {
                                this.cbo_CollapseMappingTable.SelectedIndex = i;
                                break;
                            }
                        }
                    }
                }

                TableColumn[] tgtCols = null;
                if(!string.IsNullOrEmpty(this._CollapseComponent.TgtConnStr) && 
                    !string.IsNullOrEmpty(this._CollapseComponent.CollapseInstanceTable))
                {
                    tgtCols = DbUtil.GetTableColumns(DataProviderType.MSSQL, this._CollapseComponent.TgtConnStr,
                                                     string.Empty, this._CollapseComponent.CollapseInstanceTable);
                }

                List<string> srcFields = new List<string>();
                if(!string.IsNullOrEmpty(this._CollapseComponent.CollapsedIdAttributeName))
                {
                    srcFields.Add(this._CollapseComponent.CollapsedIdAttributeName);
                }
                foreach(AttributeMetaData attrMetaData in this._CollapseComponent.AttrMetaDatas)
                {
                    if (attrMetaData.AttributeType == AttributeType.CompositeAttribute)
                    {
                        foreach (string attrName in attrMetaData.ArgNameAttrNameBindings.Values)
                        {
                            if (!srcFields.Contains(attrName))
                                srcFields.Add(attrName);
                        }
                    }
                    else
                    {
                        if (!srcFields.Contains(attrMetaData.AttributeName))
                            srcFields.Add(attrMetaData.AttributeName);
                    }
                }

                foreach(string srcField in srcFields)
                {
                    DataGridViewRow dr = new DataGridViewRow();
                    DataGridViewTextBoxCell cellSrc = new DataGridViewTextBoxCell();
                    cellSrc.Value = srcField;
                    dr.Cells.Add(cellSrc);

                    DataGridViewComboBoxCell cellTgt = new DataGridViewComboBoxCell();
                    if(tgtCols !=null && tgtCols.Length>0)
                    {
                        foreach(TableColumn tgtCol in tgtCols)
                        {
                            cellTgt.Items.Add(tgtCol.ColumnName);
                        }
                    }
                    if(this._CollapseComponent.CollapseInstanceFieldMappings !=null && 
                        this._CollapseComponent.CollapseInstanceFieldMappings.ContainsKey(srcField))
                    {
                        cellTgt.Value = this._CollapseComponent.CollapseInstanceFieldMappings[srcField];
                    }
                    dr.Cells.Add(cellTgt);

                    this.dv_CollapseInstanceFields.Rows.Add(dr);
                }

                this.cbo_MappingTableEntityIDField.Items.Clear();
                this.cbo_MappingTableCollapseIDField.Items.Clear();
                this.cbo_MappingTableScoreField.Items.Clear();
                this.cbo_MappingTraceField.Items.Clear();
                if(!string.IsNullOrEmpty(this._CollapseComponent.TgtConnStr) && 
                    !string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingTable))
                {
                    TableColumn[] cols2 = DbUtil.GetTableColumns(
                        DataProviderType.MSSQL,
                        this._CollapseComponent.TgtConnStr,
                        string.Empty, this._CollapseComponent.CollapseMappingTable);
                    if(cols2 !=null && cols2.Length>0)
                    {
                        foreach(TableColumn col in cols2)
                        {
                            this.cbo_MappingTableScoreField.Items.Add(col.ColumnName);
                            this.cbo_MappingTableEntityIDField.Items.Add(col.ColumnName);
                            this.cbo_MappingTableCollapseIDField.Items.Add(col.ColumnName);
                            this.cbo_MappingTraceField.Items.Add(col.ColumnName);
                        }

                        if (!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingEntityIDField))
                        {
                            for (int i = 0; i < this.cbo_MappingTableEntityIDField.Items.Count; i++)
                            {
                                if (this.cbo_MappingTableEntityIDField.Items[i].ToString() == this._CollapseComponent.CollapseMappingEntityIDField)
                                {
                                    this.cbo_MappingTableEntityIDField.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                        if (!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingCollapseIDField))
                        {
                            for (int i = 0; i < this.cbo_MappingTableCollapseIDField.Items.Count; i++)
                            {
                                if (this.cbo_MappingTableCollapseIDField.Items[i].ToString() == this._CollapseComponent.CollapseMappingCollapseIDField)
                                {
                                    this.cbo_MappingTableCollapseIDField.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                        if (!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingScoreField))
                        {
                            for (int i = 0; i < this.cbo_MappingTableScoreField.Items.Count; i++)
                            {
                                if (this.cbo_MappingTableScoreField.Items[i].ToString() == this._CollapseComponent.CollapseMappingScoreField)
                                {
                                    this.cbo_MappingTableScoreField.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                        if(!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingTraceField))
                        {
                            for(int i=0;i<this.cbo_MappingTraceField.Items.Count;i++)
                            {
                                if(this.cbo_MappingTraceField.Items[i].ToString()==this._CollapseComponent.CollapseMappingTraceField)
                                {
                                    this.cbo_MappingTraceField.SelectedIndex = i;
                                    break;
                                }
                            }
                        }
                    }
                }

                this.PopulateMappingTableFieldMappings(this._CollapseComponent.MappingTableFieldMappings);
            }
            else
            {
                this.rd_TgtFile.Checked = true;
                this.txt_ResultFilePath.Text = this._CollapseComponent.CollapseResultFilePath;
            }
        }

        public void SaveSettings()
        {
            if(this.ck_PartitionProvider.Checked)
            {
                this._CollapseComponent.PartitionedEntityProviderFilePath = this.txt_EntityProviderFilePath.Text;
            }
            else
            {
                this._CollapseComponent.PartitionedEntityProviderFilePath = string.Empty;
            }
            this._CollapseComponent.DbProvider = (DataProviderType)this.cbo_DbProvider.SelectedIndex;
            this._CollapseComponent.ConnStr = this.txt_ConnStr.Text;
            this._CollapseComponent.SelectSql = this.rt_SQL.Text;
            this._CollapseComponent.IdAttributeName = this.cbo_IdAttribute.Text;
            this._CollapseComponent.CollapsedIdAttributeName = this.cbo_TgtInstanceCollapseIDField.Text;
            
            // attr
            this._CollapseComponent.AttrMetaDatas = new List<AttributeMetaData>();
            foreach (DataGridViewRow dr in this.dv_Attributes.Rows)
            {
                if (!dr.IsNewRow && dr.Cells[0].Value != null)
                {
                    string attrName = ((DataGridViewTextBoxCell)dr.Cells[0]).Value.ToString();
                    AttributeType attrType = AttributeType.NativeAttribute;
                    for (int i = 0; i <= 4; i++)
                    {
                        if (dr.Cells[1].Value.ToString() == ((AttributeType)i).ToString())
                        {
                            attrType = (AttributeType)i;
                            break;
                        }
                    }
                    double posW = double.Parse(dr.Cells[2].Value.ToString());
                    double negW = double.Parse(dr.Cells[3].Value.ToString());
                    string comparerName = (string)((DataGridViewComboBoxCell)dr.Cells[4]).Value;
                    IAttributeDistanceCalcutor comparer = null;
                    if (comparerName != null && this._Comparers.ContainsKey(comparerName))
                    {
                        comparer = this._Comparers[comparerName];
                    }
                    bool isExternalAttr = (bool)dr.Cells[5].Value;
                    DataProviderType dbProvider = DataProviderType.MSSQL;
                    if (((string)dr.Cells[6].Value) == DataProviderType.Oracle.ToString())
                        dbProvider = DataProviderType.Oracle;
                    string connStr = dr.Cells[7].Value.ToString();
                    string sql = dr.Cells[8].Value.ToString();
                    Dictionary<string, string> comparerSettings = new Dictionary<string, string>();
                    if(dr.Cells[9].Value !=null && dr.Cells[9].Value.ToString().Length>0)
                    {
                        string[] settingStrs = StringUtil.Split(dr.Cells[9].Value.ToString(), ",");
                        foreach(string settingStr in settingStrs)
                        {
                            string[] nameValPair = StringUtil.Split(settingStr, ":=");
                            if(nameValPair.Length==2)
                            {
                                comparerSettings.Add(nameValPair[0],nameValPair[1]);
                            }
                        }
                    }
                    if (attrType == AttributeType.CompositeAttribute)
                    {
                        Dictionary<string, string> bindings = new Dictionary<string, string>();
                        string[] argAttrPairs = StringUtil.Split(attrName, ",");
                        foreach (string argAttrPair in argAttrPairs)
                        {
                            string[] pair = StringUtil.Split(argAttrPair, "=");
                            if (pair.Length == 2)
                            {
                                bindings.Add(pair[0], pair[1]);
                            }
                        }

                        
                        AttributeMetaData attrMetaData =
                            new AttributeMetaData(bindings,
                                                  comparer.GetType().Assembly.GetName().Name,
                                                  comparer.GetType().FullName, comparerSettings, 
                                                  posW, negW,
                                                  isExternalAttr, dbProvider, connStr, sql);
                        this._CollapseComponent.AttrMetaDatas.Add(attrMetaData);
                    }
                    else
                    {
                        AttributeMetaData attrMetaData =
                            new AttributeMetaData(attrName, attrType,
                                                  comparer.GetType().Assembly.GetName().Name,
                                                  comparer.GetType().FullName, comparerSettings, posW, negW,
                                                  isExternalAttr, dbProvider, connStr, sql);
                        this._CollapseComponent.AttrMetaDatas.Add(attrMetaData);
                    }
                }
            }

            // threshold
            if(this.ck_NativeAttrThreshold.Checked)
                this._CollapseComponent.NativeAttributeThreshold = (double)this.num_NativeAttrThreshold.Value;
            else
                this._CollapseComponent.NativeAttributeThreshold = 0;
            if (this.ck_AssociativeAttrThreshold.Checked)
                this._CollapseComponent.AssociativeAttributeThreshold = (double)this.num_AssociativeAttrThreshold.Value;
            else
                this._CollapseComponent.AssociativeAttributeThreshold = 0;
            if (this.ck_CollapseThreshold.Checked)
                this._CollapseComponent.CollapseScoreThreshold = (double)this.num_CollapseThreshold.Value;
            else
                this._CollapseComponent.CollapseScoreThreshold = 0;

            // collapse 
            if (this.cbo_CollapseCalc.SelectedIndex >= 0)
                this._CollapseComponent.CollapseCalculatorTypeName = this.cbo_CollapseCalc.SelectedItem.ToString();
            else
            {
                MessageBox.Show("Select collapse calc");
                this.cbo_CollapseCalc.Focus();
                return;
            }

            // partitions  
            this._CollapseComponent.PartitionAttributes=new Dictionary<string, EntityPartitionAttribute>();
            if(this.dv_ClusterAttributes.Rows.Count>0)
            {
                foreach(DataGridViewRow dr in this.dv_ClusterAttributes.Rows)
                {
                    if(!dr.IsNewRow && dr.Cells[0].Value !=null)
                    {
                        string attrName = dr.Cells[0].Value.ToString();
                        bool isExternal = bool.Parse(dr.Cells[1].Value.ToString());
                        DataProviderType dbProvider = DataProviderType.MSSQL;
                        if(dr.Cells[2].Value.ToString()==DataProviderType.Oracle.ToString())
                            dbProvider = DataProviderType.Oracle;
                        string connStr = dr.Cells[3].Value.ToString();
                        string selectSql = dr.Cells[4].Value.ToString();
                        string sql = selectSql;
                        if (sql.IndexOf("{0}") > 0)
                            sql = sql.Replace("{0}", "1");
                        string entityIDField = dr.Cells[5].Value.ToString();
                        SqlDbType dbType = SqlDbType.Int;
                        if(!string.IsNullOrEmpty(connStr) && !string.IsNullOrEmpty(sql))
                        {
                            TableColumn col = DbUtil.GetTableColumn(
                                dbProvider, connStr, sql, attrName);
                            dbType = col.DbType;    
                        }
                        EntityPartitionAttribute partAttr=new EntityPartitionAttribute(
                            isExternal, attrName, dbProvider,
                            connStr, selectSql, entityIDField, dbType);
                        this._CollapseComponent.PartitionAttributes.Add(attrName, partAttr);
                    }
                }
            }

            // merges 
            this._CollapseComponent.MergeableAttributeNames = new List<List<string>>();
            foreach(DataGridViewRow dr in this.dv_MergeableAttrs.Rows)
            {
                if(!dr.IsNewRow && dr.Cells[0].Value !=null)
                {
                    string[] attrNames = StringUtil.Split(dr.Cells[0].Value.ToString());
                    if(attrNames !=null && attrNames.Length>0)
                    {
                        List<string> attrNameList=new List<string>();
                        attrNameList.AddRange(attrNames);
                        this._CollapseComponent.MergeableAttributeNames.Add(attrNameList);
                    }
                }
            }

            // output 
            if (this.rd_TgtFile.Checked)
            {
                this._CollapseComponent.CollapseResultFilePath = this.txt_ResultFilePath.Text;
                this._CollapseComponent.TgtConnStr = string.Empty;
                this._CollapseComponent.CollapseInstanceTable = string.Empty;
                this._CollapseComponent.CollapseInstanceFieldMappings = new Dictionary<string, string>();
                this._CollapseComponent.CollapseMappingTable = string.Empty;
                this._CollapseComponent.CollapseMappingEntityIDField = string.Empty;
                this._CollapseComponent.CollapseMappingCollapseIDField = string.Empty;
                this._CollapseComponent.CollapseMappingScoreField = string.Empty;
                this._CollapseComponent.MappingTableFieldMappings=new Dictionary<string, string>();
            }
            else
            {
                this._CollapseComponent.CollapseResultFilePath = string.Empty;
                this._CollapseComponent.TgtConnStr = this.txt_TgtConnStr.Text;
                this._CollapseComponent.CollapseInstanceTable = this.cbo_CollapseInstanceTable.Text;
                this._CollapseComponent.CollapseInstanceFieldMappings = new Dictionary<string, string>();
                foreach(DataGridViewRow dr in this.dv_CollapseInstanceFields.Rows)
                {
                    if(!dr.IsNewRow && dr.Cells[0].Value !=null && dr.Cells[1].Value !=null)
                    {
                        string srcField = (string)dr.Cells[0].Value;
                        string tgtField = (string) dr.Cells[1].Value;
                        this._CollapseComponent.CollapseInstanceFieldMappings.Add(srcField, tgtField);
                    }
                }
                this._CollapseComponent.CollapseMappingTable = this.cbo_CollapseMappingTable.Text;
                this._CollapseComponent.CollapseMappingEntityIDField = this.cbo_MappingTableEntityIDField.Text;
                this._CollapseComponent.CollapseMappingCollapseIDField = this.cbo_MappingTableCollapseIDField.Text;
                this._CollapseComponent.CollapseMappingScoreField = this.cbo_MappingTableScoreField.Text;
                this._CollapseComponent.CollapseMappingTraceField = this.cbo_MappingTraceField.Text;
                this._CollapseComponent.MappingTableFieldMappings = this.GetMappingTableFieldMappings();
            }
        }

        public TestResult Test()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region source type switch

        private void ck_PartitionProvider_CheckedChanged(object sender, EventArgs e)
        {
            if(this.ck_PartitionProvider.Checked)
            {
                this.txt_EntityProviderFilePath.Enabled = true;
                this.btn_BrowseDataSource.Enabled = true;
            }
            else
            {
                this.txt_EntityProviderFilePath.Enabled = false;
                this.btn_BrowseDataSource.Enabled = false;
            }
        }
        #endregion

        #region data source
        private void btn_BrowseDataSource_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Input entities (*.xml)|*.xml|All files(*.*)|*.*";
            if(dlg.ShowDialog()==DialogResult.OK)
            {
                this.txt_EntityProviderFilePath.Text = dlg.FileName;
            }
        }

        private void btn_Update_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(this.txt_ConnStr.Text) && 
                !string.IsNullOrEmpty(this.rt_SQL.Text))
            {
                DataProviderType dbProvider = DataProviderType.MSSQL;
                if (this.cbo_DbProvider.SelectedIndex == 1)
                    dbProvider = DataProviderType.Oracle;

                TableColumn[] cols = DbUtil.GetTableColumns(dbProvider, this.txt_ConnStr.Text, this.rt_SQL.Text);
                if(cols !=null && cols.Length>0)
                {
                    this.cbo_IdAttribute.Items.Clear();
                    this.cbo_PartitionAttribute.Items.Clear();
                    foreach(TableColumn col in cols)
                    {
                        this.cbo_IdAttribute.Items.Add(col.ColumnName);
                        this.cbo_PartitionAttribute.Items.Add(col.ColumnName);
                    }

                    if (this.cbo_IdAttribute.Items.Count > 0 && !string.IsNullOrEmpty(this._CollapseComponent.IdAttributeName))
                    {
                        for (int i = 0; i < this.cbo_IdAttribute.Items.Count; i++)
                        {
                            if (this.cbo_IdAttribute.Items[i].ToString() == this._CollapseComponent.IdAttributeName)
                            {
                                this.cbo_IdAttribute.SelectedIndex = i;
                                break;
                            }
                        }
                    }

                    // additional attribute name from external queries
                    if(this._CollapseComponent.AttrMetaDatas !=null && this._CollapseComponent.AttrMetaDatas.Count>0)
                    {
                        foreach(AttributeMetaData attrMetaData in this._CollapseComponent.AttrMetaDatas)
                        {
                            if(attrMetaData.AttributeType==AttributeType.CompositeAttribute)
                            {
                                foreach(string attrName in attrMetaData.ArgNameAttrNameBindings.Values)
                                {
                                    this.AddAttributeForPerformanceFilter(attrName);
                                }
                            }
                            else
                            {
                                this.AddAttributeForPerformanceFilter(attrMetaData.AttributeName);
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region attributes
        private void btn_AddAttribute_Click(object sender, EventArgs e)
        {
            if (this.cbo_Comparers.SelectedIndex >= 0 &&
                !string.IsNullOrEmpty(this.txt_ConnStr.Text) &&
                !string.IsNullOrEmpty(this.rt_SQL.Text))
            {
                DataProviderType dbProvider = (DataProviderType)this.cbo_DbProvider.SelectedIndex;
                TableColumn[] cols =
                    DbUtil.GetTableColumns(dbProvider, this.txt_ConnStr.Text, this.rt_SQL.Text);
                string comparerName = this.cbo_Comparers.SelectedItem.ToString();
                IAttributeDistanceCalcutor comparer = this._Comparers[comparerName];
                NewAttributeComparer newAttrEditor = new NewAttributeComparer();
                newAttrEditor.Show(this);
                List<string> fieldNames = new List<string>();
                foreach (TableColumn col in cols)
                {
                    fieldNames.Add(col.ColumnName);
                }
                newAttrEditor.LoadSettings(comparer, fieldNames);
                newAttrEditor.OnAttributeMetaDataAdded += new AttributeMetaDataAdded(newAttrEditor_OnAttributeMetaDataAdded);
            }
        }

        void newAttrEditor_OnAttributeMetaDataAdded(AttributeMetaData attrMetaData)
        {
            DataGridViewRow dr = new DataGridViewRow();
            DataGridViewTextBoxCell cellAttrName = new DataGridViewTextBoxCell();
            if (attrMetaData.AttributeType == AttributeType.CompositeAttribute)
            {
                string binding = string.Empty;
                string[] argNames = new string[attrMetaData.ArgNameAttrNameBindings.Count];
                attrMetaData.ArgNameAttrNameBindings.Keys.CopyTo(argNames, 0);
                for (int i = 0; i < argNames.Length; i++)
                {
                    binding += argNames[i] + "=" + attrMetaData.ArgNameAttrNameBindings[argNames[i]];
                    if (i < argNames.Length - 1)
                        binding += ",";
                }
                cellAttrName.Value = binding;
            }
            else
            {
                cellAttrName.Value = attrMetaData.AttributeName;
            }
            dr.Cells.Add(cellAttrName);

            DataGridViewComboBoxCell cellAttrType = new DataGridViewComboBoxCell();
            for (int i = 0; i <= 4; i++)
            {
                AttributeType attrType = (AttributeType) i;
                cellAttrType.Items.Add(attrType.ToString());
            }
            cellAttrType.Value = attrMetaData.AttributeType.ToString();
            dr.Cells.Add(cellAttrType);

            DataGridViewTextBoxCell cellPosW = new DataGridViewTextBoxCell();
            cellPosW.Value = attrMetaData.PositiveMatchWeight;
            dr.Cells.Add(cellPosW);
            DataGridViewTextBoxCell cellNegW = new DataGridViewTextBoxCell();
            cellNegW.Value = attrMetaData.NegativeMatchWeight;
            dr.Cells.Add(cellNegW);

            DataGridViewComboBoxCell cellComparer = new DataGridViewComboBoxCell();
            foreach (string comparerName1 in this._Comparers.Keys)
            {
                cellComparer.Items.Add(comparerName1);
            }
            cellComparer.Value = attrMetaData.ComparerTypeName;
            dr.Cells.Add(cellComparer);

            DataGridViewCheckBoxCell cellExternal = new DataGridViewCheckBoxCell();
            cellExternal.Value = attrMetaData.IsExternalAttribute;
            dr.Cells.Add(cellExternal);

            DataGridViewComboBoxCell cellDbProvider = new DataGridViewComboBoxCell();
            for (int i = 0; i <= 1; i++)
            {
                cellDbProvider.Items.Add(((DataProviderType) i).ToString());
            }
            cellDbProvider.Value = attrMetaData.ExternalAttributeDbProvider.ToString();
            dr.Cells.Add(cellDbProvider);

            DataGridViewTextBoxCell cellConnStr = new DataGridViewTextBoxCell();
            cellConnStr.Value = attrMetaData.ExternalAttributeConnStr;
            dr.Cells.Add(cellConnStr);

            DataGridViewTextBoxCell cellSql = new DataGridViewTextBoxCell();
            cellSql.Value = attrMetaData.ExternalAttributeSelectSql;
            dr.Cells.Add(cellSql);

            DataGridViewTextBoxCell cellSettings = new DataGridViewTextBoxCell();
            string settings = string.Empty;
            if (attrMetaData.ComparerSettings != null && attrMetaData.ComparerSettings.Count > 0)
            {
                string[] names = new string[attrMetaData.ComparerSettings.Count];
                attrMetaData.ComparerSettings.Keys.CopyTo(names, 0);
                for (int i = 0; i < names.Length; i++)
                {
                    settings += names[i] + ":=" + attrMetaData.ComparerSettings[names[i]];
                    if (i < names.Length - 1)
                        settings += ",";
                }
            }
            cellSettings.Value = settings;
            dr.Cells.Add(cellSettings);

            this.dv_Attributes.Rows.Add(dr);

            if (attrMetaData.AttributeType == AttributeType.CompositeAttribute)
            {
                string[] attrNames = new string[attrMetaData.ArgNameAttrNameBindings.Count];
                attrMetaData.ArgNameAttrNameBindings.Values.CopyTo(attrNames, 0);
                foreach (string attrName in attrNames)
                {
                    this.AddAttributeToInstanceTableFieldBinding(attrName);
                    this.AddAttributeForPerformanceFilter(attrName);
                }
            }
            else
            {
                this.AddAttributeToInstanceTableFieldBinding(attrMetaData.AttributeName);
                this.AddAttributeForPerformanceFilter(attrMetaData.AttributeName);
            }


            this.clb_AvailableMergeableAttrs.Items.Add(attrMetaData.AttributeName);
        }

        private void AddAttributeToInstanceTableFieldBinding(string attrName)
        {
            DataGridViewRow dr = new DataGridViewRow();
            DataGridViewTextBoxCell cellAttrName = new DataGridViewTextBoxCell();
            cellAttrName.Value = attrName;
            dr.Cells.Add(cellAttrName);
            DataGridViewComboBoxCell cellTgtField = new DataGridViewComboBoxCell();
            if(!string.IsNullOrEmpty(this.txt_TgtConnStr.Text) && this.cbo_CollapseInstanceTable.SelectedIndex>=0)
            {
                string connStr = this.txt_TgtConnStr.Text;
                string tblName = this.cbo_CollapseInstanceTable.SelectedItem.ToString();
                TableColumn[] cols = DbUtil.GetTableColumns(DataProviderType.MSSQL, connStr, string.Empty, tblName);
                foreach(TableColumn col in cols)
                {
                    cellTgtField.Items.Add(col.ColumnName);
                }
            }
            dr.Cells.Add(cellTgtField);

            this.dv_CollapseInstanceFields.Rows.Add(dr);
        }

        private void AddAttributeForPerformanceFilter(string attrName)
        {
            bool exist = false;
            for (int i = 0; i < this.cbo_PartitionAttribute.Items.Count; i++)
            {
                if (this.cbo_PartitionAttribute.Items[i].ToString() == attrName)
                {
                    exist = true;
                    break;
                }
            }
            if(!exist)
            {
                this.cbo_PartitionAttribute.Items.Add(attrName);
            }
        }
        #endregion

        #region thresholds
        private void ck_NativeAttrThreshold_CheckedChanged(object sender, EventArgs e)
        {
            if (this.ck_NativeAttrThreshold.Checked)
                this.num_NativeAttrThreshold.Enabled = true;
            else
                this.num_NativeAttrThreshold.Enabled = false;
        }

        private void ck_AssociativeAttrThreshold_CheckedChanged(object sender, EventArgs e)
        {
            if (this.ck_AssociativeAttrThreshold.Checked)
                this.num_AssociativeAttrThreshold.Enabled = true;
            else
                this.num_AssociativeAttrThreshold.Enabled = false;
        }

        private void ck_CollapseThreshold_CheckedChanged(object sender, EventArgs e)
        {
            if (this.ck_CollapseThreshold.Checked)
                this.num_CollapseThreshold.Enabled = true;
            else
                this.num_CollapseThreshold.Enabled = false;
        }
        #endregion

        #region performance
        private void btn_AddClusterAttribute_Click(object sender, EventArgs e)
        {
            string attrName = this.cbo_PartitionAttribute.Text;
            bool isExternal = this.ck_PartitionIsExternal.Checked;
            DataProviderType dbProvider = DataProviderType.MSSQL;
            string connStr = string.Empty;
            string sql = string.Empty;
            string entityIDField = string.Empty;
            SqlDbType dbType = SqlDbType.Int;
            if(isExternal)
            {
                dbProvider = (DataProviderType)this.cbo_PartitionDbProvider.SelectedIndex;
                connStr = this.txt_PartitionConnStr.Text;
                sql = this.rt_PartitionSql.Text;
                if (sql.IndexOf("{0}") > 0)
                    sql = sql.Replace("{0}", "1");
                entityIDField = this.cbo_PartitionEntityIDField.Text;
                TableColumn col = DbUtil.GetTableColumn(
                    dbProvider, connStr, sql, attrName);
                dbType = col.DbType;
            }
            
            EntityPartitionAttribute partAttr = new EntityPartitionAttribute(
                isExternal, attrName,dbProvider,
                connStr, this.rt_PartitionSql.Text, entityIDField, dbType);

            DataGridViewRow dr = new DataGridViewRow();

            DataGridViewTextBoxCell cellAttrNames = new DataGridViewTextBoxCell();
            cellAttrNames.Value = partAttr.PartitionAttributeName;
            dr.Cells.Add(cellAttrNames);

            DataGridViewCheckBoxCell cellExt = new DataGridViewCheckBoxCell();
            cellExt.Value = partAttr.IsExternal;
            dr.Cells.Add(cellExt);

            DataGridViewComboBoxCell cellDbProvider = new DataGridViewComboBoxCell();
            cellDbProvider.Items.Add(DataProviderType.MSSQL.ToString());
            cellDbProvider.Items.Add(DataProviderType.Oracle.ToString());
            cellDbProvider.Value = partAttr.DbProvider.ToString();
            dr.Cells.Add(cellDbProvider);

            DataGridViewTextBoxCell cellConnStr = new DataGridViewTextBoxCell();
            cellConnStr.Value = partAttr.ConnStr;
            dr.Cells.Add(cellConnStr);

            DataGridViewTextBoxCell cellSql = new DataGridViewTextBoxCell();
            cellSql.Value = partAttr.SelectSql;
            dr.Cells.Add(cellSql);

            DataGridViewTextBoxCell cellEntityIDField = new DataGridViewTextBoxCell();
            cellEntityIDField.Value = partAttr.EntityIDFieldName;
            dr.Cells.Add(cellEntityIDField);

            this.dv_ClusterAttributes.Rows.Add(dr);
        }
        #endregion

        

        private void btn_Test_Click(object sender, EventArgs e)
        {
            TestResult result = this.Test();
            MessageBox.Show(result.Message);
        }

        private void btn_OK_Click(object sender, EventArgs e)
        {
            this.SaveSettings();
            if (this.UpdateComponentSettingEvent != null)
                this.UpdateComponentSettingEvent(this._ActivityNode, this._CollapseComponent);

            this.Close();
        }

        private void btn_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_SaveOutput_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "Partition result files(*.xml)|*.xml|All files(*.*)|*.*";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                this.txt_ResultFilePath.Text = dlg.FileName;
            }
        }

        #region output
        private void rd_TgtFile_CheckedChanged(object sender, EventArgs e)
        {
            if(this.rd_TgtFile.Checked)
            {
                this.txt_ResultFilePath.Enabled = true;
                this.btn_SaveOutput.Enabled = true;
                this.cbo_CollapseInstanceTable.Enabled = false;
                this.btn_UpdateTgtTable.Enabled = false;
                this.txt_TgtConnStr.Enabled = false;
                this.dv_CollapseInstanceFields.Enabled = false;
                this.cbo_CollapseMappingTable.Enabled = false;
                this.cbo_MappingTableScoreField.Enabled = false;
                this.cbo_MappingTableEntityIDField.Enabled = false;
                this.cbo_MappingTableCollapseIDField.Enabled = false;
            }
            else
            {
                this.txt_ResultFilePath.Enabled = false;
                this.btn_SaveOutput.Enabled = false;
                this.cbo_CollapseInstanceTable.Enabled = true;
                this.btn_UpdateTgtTable.Enabled = true;
                this.txt_TgtConnStr.Enabled = true;
                this.dv_CollapseInstanceFields.Enabled = true;
                this.cbo_CollapseMappingTable.Enabled = true;
                this.cbo_MappingTableScoreField.Enabled = true;
                this.cbo_MappingTableEntityIDField.Enabled = true;
                this.cbo_MappingTableCollapseIDField.Enabled = true;
            }
        }

        private void rd_TgtDB_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rd_TgtFile.Checked)
            {
                this.txt_ResultFilePath.Enabled = true;
                this.btn_SaveOutput.Enabled = true;
                this.cbo_CollapseInstanceTable.Enabled = false;
                this.btn_UpdateTgtTable.Enabled = false;
                this.txt_TgtConnStr.Enabled = false;
                this.dv_CollapseInstanceFields.Enabled = false;
                this.cbo_CollapseMappingTable.Enabled = false;
                this.cbo_MappingTableScoreField.Enabled = false;
                this.cbo_MappingTableEntityIDField.Enabled = false;
                this.cbo_MappingTableCollapseIDField.Enabled = false;
            }
            else
            {
                this.txt_ResultFilePath.Enabled = false;
                this.btn_SaveOutput.Enabled = false;
                this.cbo_CollapseInstanceTable.Enabled = true;
                this.btn_UpdateTgtTable.Enabled = true;
                this.txt_TgtConnStr.Enabled = true;
                this.dv_CollapseInstanceFields.Enabled = true;
                this.cbo_CollapseMappingTable.Enabled = true;
                this.cbo_MappingTableScoreField.Enabled = true;
                this.cbo_MappingTableEntityIDField.Enabled = true;
                this.cbo_MappingTableCollapseIDField.Enabled = true;
            }
        }

        private void btn_UpdateTgtTable_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(this.txt_TgtConnStr.Text))
            {
                string[] tblNames =
                    DbUtil.GetTableNames(DataProviderType.MSSQL, string.Empty, this.txt_TgtConnStr.Text);
                this.cbo_CollapseInstanceTable.Items.Clear();
                this.cbo_CollapseMappingTable.Items.Clear();

                if (tblNames != null && tblNames.Length > 0)
                {
                    foreach (string tblName in tblNames)
                    {
                        this.cbo_CollapseInstanceTable.Items.Add(tblName);
                        this.cbo_CollapseMappingTable.Items.Add(tblName);
                    }
                }

                if (this.cbo_CollapseInstanceTable.Items.Count > 0 && !string.IsNullOrEmpty(this._CollapseComponent.CollapseInstanceTable))
                {
                    for (int i = 0; i < this.cbo_CollapseInstanceTable.Items.Count; i++)
                    {
                        if (this.cbo_CollapseInstanceTable.Items[i].ToString() == this._CollapseComponent.CollapseInstanceTable)
                        {
                            this.cbo_CollapseInstanceTable.SelectedIndex = i;
                            break;
                        }
                    }
                }

                if(this.cbo_CollapseMappingTable.Items.Count>0 && !string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingTable))
                {
                    for(int i=0;i<this.cbo_CollapseMappingTable.Items.Count;i++)
                    {
                        if(this.cbo_CollapseMappingTable.Items[i].ToString()==this._CollapseComponent.CollapseMappingTable)
                        {
                            this.cbo_CollapseMappingTable.SelectedIndex = i;
                            break;
                        }
                    }
                }
            }
        }

        private void cbo_CollapseInstanceTable_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_CollapseInstanceTable.SelectedIndex>=0)
            {
                this.cbo_TgtInstanceCollapseIDField.Items.Clear();
                string instanceTblName = this.cbo_CollapseInstanceTable.SelectedItem.ToString();
                TableColumn[] cols =
                    DbUtil.GetTableColumns(DataProviderType.MSSQL,
                                           this.txt_TgtConnStr.Text, string.Empty, instanceTblName);
                if(cols !=null && cols.Length>0)
                {
                    foreach(TableColumn col in cols)
                    {
                        this.cbo_TgtInstanceCollapseIDField.Items.Add(col.ColumnName);
                    }

                    if(!string.IsNullOrEmpty(this._CollapseComponent.CollapsedIdAttributeName))
                    {
                        for(int i=0; i < this.cbo_TgtInstanceCollapseIDField.Items.Count;i++)
                        {
                            if(this.cbo_TgtInstanceCollapseIDField.Items[i].ToString()== 
                                this._CollapseComponent.CollapsedIdAttributeName)
                            {
                                this.cbo_TgtInstanceCollapseIDField.SelectedIndex = i;
                                break;
                            }
                        }
                    }
                }
                foreach(DataGridViewRow dr in this.dv_CollapseInstanceFields.Rows)
                {
                    DataGridViewComboBoxCell cellTgt = (DataGridViewComboBoxCell) dr.Cells[1];

                    cellTgt.Items.Clear();
                    if(cols !=null && cols.Length>0)
                    {
                        foreach(TableColumn col in cols)
                        {
                            cellTgt.Items.Add(col.ColumnName);
                        }
                    }
                }
            }
        }

        private void cbo_CollapseMappingTable_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_CollapseMappingTable.SelectedIndex>=0)
            {
                string mappingTblName = this.cbo_CollapseMappingTable.SelectedItem.ToString();
                TableColumn[] cols =
                    DbUtil.GetTableColumns(DataProviderType.MSSQL,
                                           this.txt_TgtConnStr.Text, string.Empty, mappingTblName);
                this.cbo_MappingTableCollapseIDField.Items.Clear();
                this.cbo_MappingTableEntityIDField.Items.Clear();
                this.cbo_MappingTableScoreField.Items.Clear();
                this.cbo_MappingTraceField.Items.Clear();
                if(cols !=null && cols.Length>0)
                {
                    foreach(TableColumn col in cols)
                    {
                        this.cbo_MappingTableScoreField.Items.Add(col.ColumnName);
                        this.cbo_MappingTableEntityIDField.Items.Add(col.ColumnName);
                        this.cbo_MappingTableCollapseIDField.Items.Add(col.ColumnName);
                        this.cbo_MappingTraceField.Items.Add(col.ColumnName);
                    }

                    if(!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingEntityIDField))
                    {
                        for(int i=0;i<this.cbo_MappingTableEntityIDField.Items.Count;i++)
                        {
                            if(this.cbo_MappingTableEntityIDField.Items[i].ToString()==this._CollapseComponent.CollapseMappingEntityIDField)
                            {
                                this.cbo_MappingTableEntityIDField.SelectedIndex = i;
                                break;
                            }
                        }
                    }
                    if (!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingCollapseIDField))
                    {
                        for (int i = 0; i < this.cbo_MappingTableCollapseIDField.Items.Count; i++)
                        {
                            if (this.cbo_MappingTableCollapseIDField.Items[i].ToString() == this._CollapseComponent.CollapseMappingCollapseIDField)
                            {
                                this.cbo_MappingTableCollapseIDField.SelectedIndex = i;
                                break;
                            }
                        }
                    }
                    if (!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingScoreField))
                    {
                        for (int i = 0; i < this.cbo_MappingTableScoreField.Items.Count; i++)
                        {
                            if (this.cbo_MappingTableScoreField.Items[i].ToString() == this._CollapseComponent.CollapseMappingScoreField)
                            {
                                this.cbo_MappingTableScoreField.SelectedIndex = i;
                                break;
                            }
                        }
                    }
                    if(!string.IsNullOrEmpty(this._CollapseComponent.CollapseMappingTraceField))
                    {
                        for(int i=0;i<this.cbo_MappingTraceField.Items.Count;i++)
                        {
                            if(this.cbo_MappingTraceField.Items[i].ToString()==this._CollapseComponent.CollapseMappingTraceField)
                            {
                                this.cbo_MappingTraceField.SelectedIndex = i;
                                break;
                            }
                        }
                    }

                    foreach (DataGridViewRow dr in this.dv_MappingTableFieldMappings.Rows)
                    {
                        DataGridViewComboBoxCell cellTgt = (DataGridViewComboBoxCell)dr.Cells[1];

                        cellTgt.Items.Clear();
                        if (cols != null && cols.Length > 0)
                        {
                            foreach (TableColumn col in cols)
                            {
                                cellTgt.Items.Add(col.ColumnName);
                            }
                        }
                    }
                }
            }
        }

        private void dv_MappingTableFieldMappings_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            TableColumn[] tgtCols = null;
            if(!string.IsNullOrEmpty(this.txt_TgtConnStr.Text) && 
                this.cbo_CollapseMappingTable.SelectedIndex>=0)
            {
                DataProviderType dbProvider2 = DataProviderType.MSSQL;
                string tblName = this.cbo_CollapseMappingTable.Text;
                tgtCols = DbUtil.GetTableColumns(dbProvider2, this.txt_TgtConnStr.Text, string.Empty, tblName);
            }

            foreach(DataGridViewRow dr in this.dv_MappingTableFieldMappings.Rows)
            {
                if(dr.IsNewRow)
                {
                    DataGridViewComboBoxCell cellTgt = (DataGridViewComboBoxCell) dr.Cells[1];
                    cellTgt.Value = null;
                    cellTgt.Items.Clear();
                    if(tgtCols !=null && tgtCols.Length>0)
                    {
                        foreach(TableColumn col in tgtCols)
                        {
                            cellTgt.Items.Add(col.ColumnName);
                        }
                    }
                }
            }
        }

        private void PopulateMappingTableFieldMappings(Dictionary<string,string> fieldMappings)
        {
            TableColumn[] tgtCols = null;
            if (!string.IsNullOrEmpty(this.txt_TgtConnStr.Text) &&
                this.cbo_CollapseMappingTable.SelectedIndex >= 0)
            {
                DataProviderType dbProvider2 = DataProviderType.MSSQL;
                string tblName = this.cbo_CollapseMappingTable.Text;
                tgtCols = DbUtil.GetTableColumns(dbProvider2, this.txt_TgtConnStr.Text, string.Empty, tblName);
            }

            if(fieldMappings !=null && fieldMappings.Count>0)
            {
                foreach(string srcField in fieldMappings.Keys)
                {
                    DataGridViewRow dr = new DataGridViewRow();
                    DataGridViewTextBoxCell cellSrc = new DataGridViewTextBoxCell();
                    cellSrc.Value = srcField;
                    dr.Cells.Add(cellSrc);
                    DataGridViewComboBoxCell cellTgt = new DataGridViewComboBoxCell();
                    cellTgt.Value = null;
                    cellTgt.Items.Clear();
                    if (tgtCols != null && tgtCols.Length > 0)
                    {
                        foreach (TableColumn col in tgtCols)
                        {
                            cellTgt.Items.Add(col.ColumnName);
                            if(col.ColumnName==fieldMappings[srcField])
                                cellTgt.Value = col.ColumnName;
                        }
                    }
                    dr.Cells.Add(cellTgt);
                    this.dv_MappingTableFieldMappings.Rows.Add(dr);
                }
            }

            foreach(DataGridViewRow dr in this.dv_MappingTableFieldMappings.Rows)
            {
                if(dr.IsNewRow)
                {
                    DataGridViewComboBoxCell cellTgt = (DataGridViewComboBoxCell)dr.Cells[1];
                    cellTgt.Value = null;
                    cellTgt.Items.Clear();
                    if (tgtCols != null && tgtCols.Length > 0)
                    {
                        foreach (TableColumn col in tgtCols)
                        {
                            cellTgt.Items.Add(col.ColumnName);
                        }
                    }
                }
            }
        }

        private Dictionary<string,string> GetMappingTableFieldMappings()
        {
            Dictionary<string,string> fieldMappings=new Dictionary<string, string>();
            foreach(DataGridViewRow dr in this.dv_MappingTableFieldMappings.Rows)
            {
                if(!dr.IsNewRow && dr.Cells[0].Value !=null && dr.Cells[1].Value !=null)
                {
                    string srcField = dr.Cells[0].Value.ToString();
                    string tgtField = dr.Cells[1].Value.ToString();
                    fieldMappings.Add(srcField,tgtField);
                }
            }
            return fieldMappings;
        }
        #endregion

        private void btn_UpdatePartitionEntityIDFields_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(this.txt_PartitionConnStr.Text) && 
                !string.IsNullOrEmpty(this.rt_PartitionSql.Text))
            {
                string connStr = this.txt_PartitionConnStr.Text;
                string sql = this.rt_PartitionSql.Text;
                if (sql.IndexOf("{0}") > 0)
                    sql = sql.Replace("{0}", "1");
                DataProviderType dbProvider = (DataProviderType) this.cbo_PartitionDbProvider.SelectedIndex;
                this.cbo_PartitionEntityIDField.Items.Clear();
                TableColumn[] cols = DbUtil.GetTableColumns(
                    dbProvider, connStr, sql);
                if(cols !=null && cols.Length>0)
                {
                    foreach(TableColumn col in cols)
                    {
                        this.cbo_PartitionEntityIDField.Items.Add(col.ColumnName);
                    }
                }
            }
        }

        private void cbo_PartitionAttribute_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_PartitionAttribute.SelectedIndex>=0)
            {
                string attrName = this.cbo_PartitionAttribute.SelectedItem.ToString();
                if(this._CollapseComponent.AttrMetaDatas !=null && this._CollapseComponent.AttrMetaDatas.Count>0)
                {
                    foreach(AttributeMetaData attrMetaData in this._CollapseComponent.AttrMetaDatas)
                    {
                        if(attrMetaData.AttributeName==attrName)
                        {
                            if(attrMetaData.IsExternalAttribute)
                            {
                                this.ck_PartitionIsExternal.Checked = true;
                                this.cbo_PartitionDbProvider.SelectedIndex =
                                    (int) attrMetaData.ExternalAttributeDbProvider;
                                this.txt_PartitionConnStr.Text = attrMetaData.ExternalAttributeConnStr;
                                this.rt_PartitionSql.Text = attrMetaData.ExternalAttributeSelectSql;
                            }
                            else
                            {
                                this.ck_PartitionIsExternal.Checked = false;
                            }
                        }
                    }
                }
            }
        }

        #region mergeable attrs
        private void btn_AddMergeableAttrs_Click(object sender, EventArgs e)
        {
            List<string> attrNames=new List<string>();
            for(int i=0;i<this.clb_AvailableMergeableAttrs.Items.Count;i++)
            {
                if(this.clb_AvailableMergeableAttrs.GetItemChecked(i))
                {
                    attrNames.Add(this.clb_AvailableMergeableAttrs.Items[i].ToString());
                }
            }

            DataGridViewRow dr = new DataGridViewRow();
            DataGridViewTextBoxCell cellAttrNames=new DataGridViewTextBoxCell();
            cellAttrNames.Value = StringUtil.ToString(attrNames.ToArray());
            dr.Cells.Add(cellAttrNames);
            this.dv_MergeableAttrs.Rows.Add(dr);
        }
        #endregion
    }
}
